#ifndef __CHECKERBOARD_H__
#define __CHECKERBOARD_H__

#include "../VT100//VT100.hpp"
#include "../chess/Chess.hpp"
#include <cstdio>
#include <iostream>
#include <ostream>
#include <pthread.h>
#include <string>

#define CHESS_BOARD_MIN_X 0 // 棋盘最小X坐标
#define CHESS_BOARD_MIN_Y 1 // 棋盘最小Y坐标

#define CHESS_BOARD_MAX_X 56 // 棋盘最大X坐标
#define CHESS_BOARD_MAX_Y 29 // 棋盘最大Y坐标

#define CHESS_BOARD_ROWS 15    // 棋盘行数
#define CHESS_BOARD_COLUMNS 15 // 棋盘列数

#define CHESS_BOARD_SKIP_X 4 // X方向间隔
#define CHESS_BOARD_SKIP_Y 2 // Y方向间隔

#define CHESS_BOARD_FILENAME                                                   \
  "/home/yujiu/linux/c++/c-craftsman/project/src/checkerBoard/ChessBoard.txt"

/**
 * @brief 棋盘
 *
 */
class CheckerBoard {
public:
  CheckerBoard() {
    for (int i = 0; i < CHESS_BOARD_ROWS; i++) {
      for (int j; j < CHESS_BOARD_COLUMNS; j++) {
        chessset[i][j] = nullptr;
      }
    }
  }

  ~CheckerBoard() {
    for (int i = 0; i < CHESS_BOARD_ROWS; i++) {
      for (int j; j < CHESS_BOARD_COLUMNS; j++) {
        if (chessset[i][j] != nullptr) {
          delete chessset[i][j];
        }
      }
    }
    VT100::VT100SetTheCursor(0, CHESS_BOARD_MAX_Y + 1);
    pthread_mutex_destroy(&mutex); // 释放锁
  }

  /**
   * @brief Get the Checker Board object  获取类地址
   *
   * @return CheckerBoard*
   */
  static CheckerBoard *getCheckerBoard(void) {
    if (checkerboard == nullptr) {
      pthread_mutex_lock(&mutex);
      checkerboard = new CheckerBoard();
      pthread_mutex_unlock(&mutex);
    }
    return checkerboard;
  }

  /**
   * @brief 显示棋盘
   *
   */
  void checkerBoardShow() {
    FILE *file = fopen(CHESS_BOARD_FILENAME, "r"); // 打开文件（只读）
    if (file == NULL) {
      perror("Failed to open file");
      return;
    }
    char buffer[100];

    VT100::VT100CLear();
    VT100::VT100SetTheCursor(CHESS_BOARD_MIN_X, CHESS_BOARD_MIN_Y);

    while (fgets(buffer, sizeof(buffer), file) != NULL) { // 逐行读取
      fprintf(stdout, "%s", buffer);
    }
    VT100::VT100ClearTheConfiguration();

    fclose(file); // 关闭文件
  }

  /**
   * @brief 棋盘有效性判断
   *
   * @param chess
   * @return true
   * @return false
   */
  bool checkerBoardIsValidPosition(Chess *chess) {
    unsigned int x = 0;
    unsigned int y = 0;
    x = (chess->getDisplayPositionX() - CHESS_BOARD_MIN_X) / CHESS_BOARD_SKIP_X;
    y = (chess->getDisplayPositionY() - CHESS_BOARD_MIN_Y) / CHESS_BOARD_SKIP_Y;

    if (x >= CHESS_BOARD_COLUMNS || y >= CHESS_BOARD_ROWS ||
        chess->getDisplayPositionY() > CHESS_BOARD_MAX_Y ||
        chess->getDisplayPositionX() > CHESS_BOARD_MAX_X) {
      return false;
    } else if (chessset[y][x] != nullptr) {
      checkerBoardShowWarning("当前位置有棋子！");
      return false;
    }
    chess->setX(y);
    chess->setY(x);
    return true;
  }

  /**
   * @brief Set the Chessset object 添加棋子
   *
   * @param chess
   */
  void setChessset(Chess *chess) {
    chess->chessDisplay();
    chessset[chess->getX()][chess->getY()] = chess;
  }

  /**​
   * @brief 显示警告信息
   * @param str 要显示的警告字符串
   *
   * 在棋盘底部中央位置显示红色警告信息(蓝色背景)
   */
  void checkerBoardShowWarning(const std::string &str) {
    // 清除之前的内容(通过输出足够多的空格)
    VT100::VT100SetTheCursor(CHESS_BOARD_MAX_X * 2, CHESS_BOARD_MAX_Y / 2);
    std::cout << std::string(str.length() + 10, ' '); // 用空格覆盖旧内容

    // 显示新内容
    VT100::VT100SetColors(BG_BLUE, FG_RED);
    VT100::VT100SetTheCursor(CHESS_BOARD_MAX_X * 2, CHESS_BOARD_MAX_Y / 2);
    std::cout << str;

    VT100::VT100ClearTheConfiguration();
  }

  /**
   * @brief Get the Chess At object 获取特定位置的棋子
   *
   * @param row
   * @param col
   * @return Chess*
   */
  Chess *getChessAt(int row, int col) { return chessset[row][col]; }

private:
  static CheckerBoard *checkerboard;
  static pthread_mutex_t mutex;
  Chess *chessset[CHESS_BOARD_ROWS][CHESS_BOARD_COLUMNS];
};

pthread_mutex_t CheckerBoard::mutex = PTHREAD_MUTEX_INITIALIZER;
CheckerBoard *CheckerBoard::checkerboard = nullptr;

#endif // __CHECKERBOARD_H__